#!/bin/sh
# -*- mode: shell-script; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
#
# Add options for the script
# Copyright (C) 2020 Phytium.

PROGNAME="setup-env"

if [ -z "$ZSH_NAME" ] && echo "$0" | grep -q "$PROGNAME"; then
    echo "ERROR: This script needs to be sourced."
    SCRIPT_PATH=`readlink -f $0`
    if [ "`readlink $SHELL`" = "dash" ];then
        echo "Try run command \"set -- -h; . $SCRIPT_PATH\" to get help."
    else
        echo "Try run command \". $SCRIPT_PATH -h\" to get help."
    fi
    unset SCRIPT_PATH PROGNAME
    exit
else
    if [ -n "$BASH_SOURCE" ]; then
        ROOTDIR="`readlink -f $BASH_SOURCE | xargs dirname`"
    elif [ -n "$ZSH_NAME" ]; then
        ROOTDIR="`readlink -f $0 | xargs dirname`"
    else
        ROOTDIR="`readlink -f $PWD | xargs dirname`"
    fi
    if ! [ -e "$ROOTDIR/$PROGNAME" ];then
        echo "Go to where $PROGNAME locates, then run: . $PROGNAME <args>"
        unset ROOTDIR PROGNAME
        return
    fi
fi

# Check if current user is root
if [ "$(whoami)" = "root" ]; then
    echo "ERROR: Do not use the BSP as root. Exiting..."
    unset ROOTDIR PROGNAME
    return
fi

OEROOTDIR=${ROOTDIR}/sources/meta-phytium/poky
if [ -e ${ROOTDIR}/sources/oe-core ]; then
    OEROOTDIR=${ROOTDIR}/sources/oe-core
fi
PHYROOTDIR=${ROOTDIR}/sources/meta-phytium
PROJECT_DIR=${ROOTDIR}/build_${MACHINE}

prompt_message () {
local i=''
echo "Welcome to Phytium SDK (Reference Distro)

The Yocto Project has extensive documentation about OE including a
reference manual which can be found at:
    http://yoctoproject.org/documentation

For more information about OpenEmbedded see their website:
    http://www.openembedded.org/

You can now run 'bitbake <target>'
    core-image-minimal
    core-image-sato
    core-image-weston
    core-image-xfce
"
    echo "To return to this build environment later please run:"
    echo "    . $PROJECT_DIR/SOURCE_THIS"
}

clean_up()
{
   unset PROGNAME ROOTDIR OEROOTDIR PHYROOTDIR PROJECT_DIR \
         LAYER_LIST MACHINE FSLDISTRO EXTRAROOTDIR \
         OLD_OPTIND CPUS JOBS THREADS DOWNLOADS CACHES DISTRO \
         setup_flag setup_h setup_j setup_t setup_g setup_l setup_builddir \
         setup_download setup_sstate setup_error layer append_layer \
         valid_machine valid_num
   unset -f usage prompt_message
}

usage() {
    echo "Usage: . $PROGNAME -m <machine>"

    echo -e "\n    Supported machines:
    `find ${ROOTDIR}/sources/meta-phytium/meta-bsp/conf/machine \
        -name *.conf 2>/dev/null \
        |egrep "/(phy|d|e).*conf$" |sort \
        |xargs echo |sed -e 's,[^ ]*/,,g;s,.conf,,g'`
"

    echo "    Optional parameters:
    * [-m machine]: the target machine to be built.
    * [-j jobs]:    number of jobs for make to spawn during the compilation stage.
    * [-t tasks]:   number of BitBake tasks that can be issued in parallel.
    * [-b path]:    non-default path of project build folder.
    * [-d path]:    non-default path of DL_DIR (downloaded source)
    * [-c path]:    non-default path of SSTATE_DIR (shared state Cache)
    * [-h]:         help
"
    if [ "`readlink $SHELL`" = "dash" ];then
        echo "
    You are using dash which does not pass args when being sourced.
    To workaround this limitation, use \"set -- args\" prior to
    sourcing this script. For exmaple:
        \$ set -- -m e2000 -j 3 -t 2
        \$ . $ROOTDIR/$PROGNAME
"
    fi
}

# parse the parameters
OLD_OPTIND=$OPTIND
while getopts "m:j:t:b:d:c:h" setup_flag
do
    case $setup_flag in
        m) MACHINE="$OPTARG";
           ;;
        j) setup_j="$OPTARG";
           ;;
        t) setup_t="$OPTARG";
           ;;
        b) setup_builddir="$OPTARG";
           ;;
        d) setup_download="$OPTARG";
           ;;
        c) setup_sstate="$OPTARG";
           ;;
        h) setup_h='true';
           ;;
        ?) setup_error='true';
           ;;
    esac
done
OPTIND=$OLD_OPTIND

# check the "-h" and other not supported options
if test $setup_error || test $setup_h; then
    usage && clean_up && return
fi

# Check the machine type specified
valid_machine=false
if [ -n "${MACHINE}" ];then
    valid_num=`find ${ROOTDIR}/sources/meta-phytium/meta-bsp/conf/machine \
        -name ${MACHINE}.conf 2>/dev/null |wc -l`
    if [ "1" -lt "$valid_num" ];then
        echo "ERROR: possible error may occur due to duplicate ${MACHINE}.conf exist:"
        find ${ROOTDIR}/sources/meta-phytium/meta-bsp/conf/machine \ 
            -name ${MACHINE}.conf 2>/dev/null
        echo "Please remove the useless layer under ${ROOTDIR}/sources"
        clean_up && return
    elif [ "0" = "$valid_num" ];then
        echo "$MACHINE is not supported by this build setup."
        usage && clean_up && return
    fi
else
    usage && clean_up && return
fi

echo "Configuring for ${MACHINE} ..."
LAYER_LIST=" \
    meta-phytium/meta-bsp \
    meta-qt5 \
    meta-qt5-extra \
    meta-openembedded/meta-oe \
    meta-openembedded/meta-networking \
    meta-openembedded/meta-python \
    meta-openembedded/meta-filesystems \
    meta-openembedded/meta-gnome \
    meta-openembedded/meta-multimedia \
    meta-openembedded/meta-xfce \
    meta-openembedded/meta-initramfs \
    meta-anaconda \
    meta-phytium/meta-xenomai \
    meta-clang \
    meta-virtualization \
"

DISTRO="phytium"

# set default jobs and threads
CPUS=`grep -c processor /proc/cpuinfo`
JOBS="4"
THREADS="4"

# check optional jobs and threads
if echo "$setup_j" | egrep -q "^[0-9]+$"; then
    JOBS=$setup_j
fi
if echo "$setup_t" | egrep -q "^[0-9]+$"; then
    THREADS=$setup_t
fi

# set project folder location and name
if [ -n "$setup_builddir" ]; then
    if echo $setup_builddir |grep -q ^/;then
        PROJECT_DIR="${setup_builddir}"
    else
        PROJECT_DIR="`pwd`/${setup_builddir}"
    fi
else
    PROJECT_DIR=${ROOTDIR}/build_${MACHINE}
fi
mkdir -p $PROJECT_DIR

if [ -n "$setup_download" ]; then
    if echo $setup_download |grep -q ^/;then
        DOWNLOADS="${setup_download}"
    else
        DOWNLOADS="`pwd`/${setup_download}"
    fi
else
    DOWNLOADS="$ROOTDIR/downloads"
fi
mkdir -p $DOWNLOADS
DOWNLOADS=`readlink -f "$DOWNLOADS"`

if [ -n "$setup_sstate" ]; then
    if echo $setup_sstate |grep -q ^/;then
        CACHES="${setup_sstate}"
    else
        CACHES="`pwd`/${setup_sstate}"
    fi
else
    CACHES="$ROOTDIR/sstate-cache"
fi
mkdir -p $CACHES
CACHES=`readlink -f "$CACHES"`

# check if project folder was created before
if [ -e "$PROJECT_DIR/SOURCE_THIS" ]; then
    echo "$PROJECT_DIR was created before."
    . $PROJECT_DIR/SOURCE_THIS
    echo "Nothing is changed."
    clean_up && return
fi

# source oe-init-build-env to init build env
cd $OEROOTDIR
set -- $PROJECT_DIR
. ./oe-init-build-env > /dev/null

# if conf/local.conf not generated, no need to go further
if [ ! -e conf/local.conf ]; then
    echo "ERROR: the local.conf is not created, Exit ..."
    clean_up && cd $ROOTDIR && return
fi

# Remove comment lines and empty lines
sed -i -e '/^#.*/d' -e '/^$/d' conf/local.conf

# Change settings according to the environment
sed -e "s,MACHINE ??=.*,MACHINE ??= '$MACHINE',g" \
        -e "s,DISTRO ?=.*,DISTRO ?= '$DISTRO',g" \
        -i conf/local.conf

# Clean up PATH, because if it includes tokens to current directories somehow,
# wrong binaries can be used instead of the expected ones during task execution
export PATH="`echo $PATH | sed 's/\(:.\|:\)*:/:/g;s/^.\?://;s/:.\?$//'`"

# add layers
for layer in $(eval echo $LAYER_LIST); do
    append_layer=""
    if [ -e ${ROOTDIR}/sources/${layer} ]; then
        append_layer="${ROOTDIR}/sources/${layer}"
    fi
    if [ -n "${append_layer}" ]; then
        append_layer=`readlink -f $append_layer`
        awk '/  \042/ && !x {print "'"  ${append_layer}"' \\"; x=1} 1' \
            conf/bblayers.conf > conf/bblayers.conf~
        mv conf/bblayers.conf~ conf/bblayers.conf
    fi
done

cat >> conf/local.conf <<-EOF

# Parallelism Options
BB_NUMBER_THREADS = "$THREADS"
PARALLEL_MAKE = "-j $JOBS"
DL_DIR = "$DOWNLOADS"
SSTATE_DIR = "$CACHES"

EOF

for s in $HOME/.oe $HOME/.yocto; do
    if [ -e $s/site.conf ]; then
        echo "Linking $s/site.conf to conf/site.conf"
        ln -s $s/site.conf conf
    fi
done

# make a SOURCE_THIS file
if [ ! -e SOURCE_THIS ]; then
    echo "#!/bin/sh" >> SOURCE_THIS
    echo "cd $OEROOTDIR" >> SOURCE_THIS
    echo "set -- $PROJECT_DIR" >> SOURCE_THIS
    echo ". ./oe-init-build-env > /dev/null" >> SOURCE_THIS
    echo "echo \"Back to build project $PROJECT_DIR.\"" >> SOURCE_THIS
fi

prompt_message
cd $PROJECT_DIR
clean_up
